package com.woniuxy.project115.kaer.mall.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hankcs.hanlp.HanLP;
import com.woniuxy.project115.kaer.commons.util.OSSUtil;
import com.woniuxy.project115.kaer.mall.entity.ProductInfo;
import com.woniuxy.project115.kaer.mall.entity.ProductType;
import com.woniuxy.project115.kaer.mall.mapper.ProductInfoMapper;
import com.woniuxy.project115.kaer.mall.mapper.ProductTypeMapper;
import com.woniuxy.project115.kaer.mall.param.AddProductParam;
import com.woniuxy.project115.kaer.mall.param.FindProductParam;
import com.woniuxy.project115.kaer.mall.param.PageParam;
import com.woniuxy.project115.kaer.mall.service.ProductInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.project115.kaer.mall.util.PageInfo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lyc
 * @since 2025年02月17日
 */
@Service
public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper, ProductInfo> implements ProductInfoService {

    @Resource
    private ProductInfoMapper productInfoMapper;
    @Resource
    private ProductTypeMapper productTypeMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedisTemplate<String,Object> redisObjectTemplate;

    @Override
    public PageInfo findProductByCondition(FindProductParam param,String role) {
        // 分页
        if (param.getPageNum() == null || param.getPageSize() == null) {
            param.setPageNum(1);
            param.setPageSize(10);
        }
        Page<ProductInfo> page = new Page<>(param.getPageNum(), param.getPageSize());
        QueryWrapper<ProductInfo> productInfoQueryWrapper = new QueryWrapper<>();

        if (!StringUtils.isEmpty(param.getFindName())) {
            // 使用 HanLP 进行分词
            List<String> words = HanLP.segment(param.getFindName()).stream()
                    .map(term -> term.word)
                    .collect(Collectors.toList());;

            // 构建 OR 条件查询
            for (int i = 0; i < words.size(); i++) {
                String word = words.get(i);
                if (i > 0) {
                    productInfoQueryWrapper.or();
                }
                productInfoQueryWrapper.like("product_name", word)
                        .or()
                        .like("product_showname", word)
                        .or()
                        .like("product_brand", word)
                        .or()
                        .like("type_name", word);
            }
        }
        //如果登录角色为普通用户
        if (!role.contains("管理员")){
            // 排除库存为 0 的商品
            productInfoQueryWrapper.ne("number", 0)
                    //且处于上架中的商品
                    .eq("product_state",1);
        }else {
            //管理员可以查看未删除所有商品
            productInfoQueryWrapper.ne("product_state",2);
        }
        productInfoMapper.selectPage(page, productInfoQueryWrapper);
        return new PageInfo(page);
    }

    @Override
    public void addProduct(AddProductParam param)throws Exception {
        byte[] bytes = new byte[4];
        param.getProductImage().getInputStream().read(bytes);
        //判断是否为图片
        if (!OSSUtil.isJpg(bytes)&&!OSSUtil.isPng(bytes)) {
            throw new Exception("上传的文件不是图片");
        }
        //判断该类别是否被禁用
        ProductType productType = productTypeMapper.selectById(param.getTypeId());
        if (productType == null) {
            throw new Exception("该类别不存在");
        } else if (!(productType.getTypeState()==0)) {
            throw new Exception("该类别已被删除或禁用");
        }
        //判断该商品是否已经存在
        ProductInfo productInfo = productInfoMapper.selectOne(new QueryWrapper<ProductInfo>()
                .eq("product_name", param.getProductName())
                .eq("type_name", param.getTypeName())
                .eq("type_id", param.getTypeId()));
        if (productInfo != null) {
            throw new Exception("该商品已存在,请勿重复发布");
        }else {
            productInfo = new ProductInfo();
            productInfo.setProductName(param.getProductName());
            productInfo.setProductShowname(param.getProductShowname());
            productInfo.setProductBrand(param.getProductBrand());
            productInfo.setProductPrice(param.getProductPrice());
            productInfo.setProductDescription(param.getProductDescription());
            String originalFilename = param.getProductImage().getOriginalFilename();
            //获取后缀
            String extName = FileUtil.extName(originalFilename);
            //生成新的文件名
            String fileName = System.currentTimeMillis() + "." + extName;
            String url = OSSUtil.uploadFile(param.getProductImage().getInputStream(), fileName, "kaer-service");
            productInfo.setProductImage(url);
            productInfo.setTypeId(param.getTypeId());
            productInfo.setNumber(param.getNumber());
            productInfo.setProductState(1);
            productInfo.setTypeName(param.getTypeName());
            productInfo.setNumber(param.getNumber());
            productInfo.setFreeze(0);
            productInfo.setProductState(1);
            productInfo.setArgs(param.getArgs());
            System.out.println(param.getTypeName());
            productInfoMapper.insert(productInfo);
        }
    }

    @Override
    public void addProductNumber(Integer productId, Integer number) throws Exception {
        ProductInfo productInfo = productInfoMapper.selectById(productId);
        if (productInfo == null) {
            throw new RuntimeException("商品不存在");
        }
        //判断number是否非法
        if (number <= 0) {
            throw new Exception("数量非法");
        }
        productInfo.setNumber(productInfo.getNumber() + number);
        productInfoMapper.updateById(productInfo);
    }

    @Override
    public void upProduct(Integer productId) throws Exception {
        ProductInfo productInfo = productInfoMapper.selectById(productId);
        if (productInfo == null) {
            throw new Exception("商品不存在");
        }
        if (productInfo.getProductState()==1){
            productInfo.setProductState(0);
        } else if (productInfo.getProductState()==0) {
            productInfo.setProductState(1);
        }
        productInfoMapper.updateById(productInfo);
    }

    @Override
    public Integer collectProduct(Integer productId, Integer userId) throws Exception{
        ProductInfo productInfo = productInfoMapper.selectById(productId);
        if (productInfo == null) {
            throw new Exception("商品不存在");
        }
        if (productInfo.getProductState()==1){
            throw new Exception("商品已被删除或下架");
        }
        if (stringRedisTemplate.opsForZSet().score("user:"+userId+":collect", String.valueOf(productId)) != null) {
            stringRedisTemplate.opsForZSet().remove("user:"+userId+":collect", String.valueOf(productId));
            //取消成功后该商品在收藏排行榜中-1
            //如果该商品的收藏量在商品收藏排行榜中的数量大于1则-1，否则删除
            if (stringRedisTemplate.opsForZSet().score("collect:rank", String.valueOf(productId)) > 1) {
                stringRedisTemplate.opsForZSet().incrementScore("collect:rank", String.valueOf(productId), -1);
            } else {
                stringRedisTemplate.opsForZSet().remove("collect:rank", String.valueOf(productId));
            }
            return 1;
        }

        stringRedisTemplate.opsForZSet().add("user:"+userId+":collect", String.valueOf(productId), new Date().getTime());
        //收藏成功后该商品在收藏排行榜中+1
        stringRedisTemplate.opsForZSet().incrementScore("collect:rank", String.valueOf(productId), 1);
        return 2;
    }

    @Override
    public PageInfo selectCollect(PageParam param, Integer userId)throws Exception {
        //1.从redis里面查出收藏的商品id
        // 总条数
        Long total = stringRedisTemplate.opsForZSet().size("user:"+userId+":collect");
        //总页数
        if (param.getPageNum() == null || param.getPageSize() == null) {
            param.setPageNum(1);
            param.setPageSize(10);
        }
        Long pages = total % param.getPageSize() == 0 ? total / param.getPageSize() : total / param.getPageSize() + 1;

        long start = (param.getPageNum() - 1) * param.getPageSize();
        long end = param.getPageNum() * param.getPageSize() - 1;
        Set<String> ids = stringRedisTemplate.opsForZSet().reverseRange("user:"+userId+":collect", start, end);
        //2.根据productId 查出商品，转成Dto
        ArrayList<ProductInfo> collectProducts = new ArrayList<>();
        for (String productId : ids) {
            ProductInfo productInfo = productInfoMapper.selectById(Integer.parseInt(productId));
            collectProducts.add(productInfo);
        }
        PageInfo pageInfo = new PageInfo();
        //将查出的list 转成pageInfo
        pageInfo.setPages(pages);
        pageInfo.setTotal(total);
        pageInfo.setCurrent(param.getPageNum());
        pageInfo.setSize(param.getPageSize());
        pageInfo.setList(collectProducts);
        return pageInfo;
    }

    @Override
    public PageInfo selectShopping(PageParam param, Integer userId) {
        //1.查询出总条数
        Long total = stringRedisTemplate.opsForZSet().size("cart:list:" + userId);
        //总条数
        if (param.getPageNum() == null || param.getPageSize() == null) {
            param.setPageNum(1);
            param.setPageSize(10);
        }
        Long pages = total % param.getPageSize() == 0 ? total / param.getPageSize() : total / param.getPageSize() + 1;
        Integer start = (param.getPageNum() - 1) * param.getPageSize();
        Integer end = param.getPageSize() * param.getPageNum() - 1;

        Set<String> ids = stringRedisTemplate.opsForZSet().reverseRange("cart:list:" + userId, start, end);
        ArrayList<ProductInfo> list = new ArrayList<>();
        for (String id : ids) {
            ProductInfo productInfo = productInfoMapper.selectById(Integer.parseInt(id));
            int number = Integer.parseInt(stringRedisTemplate.opsForHash().get("cart:info:"+userId+":"+productInfo.getProductId(), "number").toString());
            productInfo.setNumber(number);
            list.add(productInfo);
        }
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPages(pages);
        pageInfo.setSize(param.getPageSize());
        pageInfo.setList(list);
        pageInfo.setCurrent(param.getPageNum());
        pageInfo.setTotal(total);

        return pageInfo;
    }

    @Override
    public void delShopping(Integer userId, Integer productId, Integer number) throws Exception {
        ProductInfo productInfo = productInfoMapper.selectById(productId);
        if (productInfo == null) {
            throw new Exception("商品不存在");
        }
        if (productInfo.getProductState() != 1) {
            throw new Exception("商品状态异常");
        }
        if (stringRedisTemplate.opsForZSet().score("cart:list:" + userId, String.valueOf(productId)) != null) {
            Integer number1 = Integer.parseInt(stringRedisTemplate.opsForHash().get("cart:info:"+userId+":"+productId, "number").toString());
            if (number >= number1) {
                stringRedisTemplate.opsForZSet().remove("cart:list:" + userId, String.valueOf(productId));
                redisObjectTemplate.delete("cart:info:"+userId+":"+productId);
            } else {
                stringRedisTemplate.opsForHash().increment("cart:info:"+userId+":"+productId, "number", -number);
            }
        } else {
            throw new Exception("购物车里无该商品");
        }
    }

    @Override
    public void changNumber(Integer userId, Integer productId, Integer number) throws Exception {
        ProductInfo productInfo = productInfoMapper.selectById(productId);
        if (productInfo == null) {
            throw new Exception("商品不存在");
        }
        if (productInfo.getProductState() != 1) {
            throw new Exception("商品状态异常");
        }
        if (productInfo.getNumber() < number) {
            throw new Exception("商品库存不够");
        }
        if (stringRedisTemplate.opsForZSet().score("cart:list:" + userId, String.valueOf(productId)) != null) {
            if (number > 0) {
                stringRedisTemplate.opsForHash().put("cart:info:"+userId+":"+productId, "number", String.valueOf(number));
            } else {
                stringRedisTemplate.opsForZSet().remove("cart:list:" + userId, String.valueOf(productId));
                redisObjectTemplate.delete("cart:info:"+userId+":"+productId);
            }
        } else {
            throw new Exception("购物车里无该商品");
        }
    }

    @Override
    public List<ProductInfo> selectCollectRank() {
        Set<String> ids = stringRedisTemplate.opsForZSet().reverseRange("collect:rank", 0, -1);
        ArrayList<ProductInfo> List = new ArrayList<>();
        for (String productId : ids) {
            ProductInfo productInfo = productInfoMapper.selectById(Integer.parseInt(productId));
            double score = stringRedisTemplate.opsForZSet().score("collect:rank", productId);
            productInfo.setNumber((int) score);
            List.add(productInfo);
        }
        return List;
    }
}